package com.achievement.service.impl.authorImpl;


import com.achievement.domain.bo.author.MedicineAuthorBO;
import com.achievement.domain.dto.author.MedicineAuthorDTO;
import com.achievement.domain.entity.author.MedicineAuthorEntity;
import com.achievement.domain.vo.author.MedicineAuthorVO;
import com.achievement.mapper.author.MedicineAuthorMapper;
import com.achievement.mappings.author.MedicineAuthorMapping;
import com.achievement.service.author.IMedicineAuthorService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;


@Service
public class MedicineAuthorServiceImpl extends ServiceImpl<MedicineAuthorMapper, MedicineAuthorEntity> implements IMedicineAuthorService {

    @Autowired
    private MedicineAuthorMapping mapping;


    @Override
    public List<MedicineAuthorEntity> getListByConditions(MedicineAuthorDTO authorDTO) {
        QueryWrapper<MedicineAuthorEntity> queryWrapper = new QueryWrapper();
        List<MedicineAuthorEntity> list = this.list(queryWrapper);
        return list;
    }

    @Override
    public MedicineAuthorVO getInfoById(String id) {
        MedicineAuthorEntity entity = this.getById(id);
        return mapping.entity2Vo(entity);
    }

    @Override
    public boolean addOrUpdate(List<MedicineAuthorDTO> list,String medicineId) {
        //获取该专利下的现有所有发明人
        MedicineAuthorDTO dto = new MedicineAuthorDTO();
        dto.setMedicineId(medicineId);
        List<MedicineAuthorEntity> medicineAuthorEntityList = getListByConditions(dto);
        Set<String> existAuthorId = medicineAuthorEntityList.stream().map(a -> a.getPersonId()).collect(Collectors.toSet());
        Set<String> authorId = list.stream().map(a -> a.getPersonId()).collect(Collectors.toSet());
        //取交集获取需要更新的数据。
        List<MedicineAuthorDTO> updateList = list.stream()
                .filter(a -> existAuthorId.contains(a.getPersonId()))
                .collect(Collectors.toList());
        //取list中personId不存在于 existAuthorId 的差集获取需要添加的数据。
        List<MedicineAuthorDTO> addList = list.stream()
                .filter(a -> !existAuthorId.contains(a.getPersonId()))
                .collect(Collectors.toList());
        //取 medicineAuthorEntityList 中personId不存在于list 的差集获取需要删除的数据。
        List<MedicineAuthorEntity> delList = medicineAuthorEntityList.stream()
                .filter(a -> !authorId.contains(a.getPersonId()))
                .collect(Collectors.toList());
        //dto->bo
        List<MedicineAuthorBO> updateBoList = updateList.stream().map(mapping::dto2Bo).collect(Collectors.toList());
        List<MedicineAuthorBO> addBoList = addList.stream().map(mapping::dto2Bo).collect(Collectors.toList());
        //bo->entity
        List<MedicineAuthorEntity> updateAuthorList = updateBoList.stream().map(mapping::bo2Entity).collect(Collectors.toList());
        List<MedicineAuthorEntity> addAuthorList = addBoList.stream().map(mapping::bo2Entity).collect(Collectors.toList());
        List<MedicineAuthorEntity> saveOrUpdateList = new ArrayList<>();
        saveOrUpdateList.addAll(updateAuthorList);
        saveOrUpdateList.addAll(addAuthorList);

        return this.saveOrUpdateBatch(saveOrUpdateList) && this.removeByIds(delList);
    }

    @Override
    public boolean add(MedicineAuthorDTO dto) {
        MedicineAuthorEntity entity = mapping.dto2Entity(dto);
        return this.updateById(entity);
    }

    @Override
    public boolean addBatch(List<MedicineAuthorDTO> list,String medicineId) {
        this.batchRemoveByMedicineIds(Arrays.asList(medicineId));
        list.forEach(a->{
            a.setMedicineId(medicineId);
        });
        List<MedicineAuthorEntity> addList = list.stream().map(mapping::dto2Entity)
                .collect(Collectors.toList());
        return this.saveBatch(addList, addList.size());
    }

    @Override
    public boolean update(MedicineAuthorDTO dto) {
        MedicineAuthorEntity entity = mapping.dto2Entity(dto);
        return this.updateById(entity);
    }

    @Override
    public boolean batchRemove(List<String> ids) {
        return this.removeByIds(ids);
    }

    @Override
    public List<MedicineAuthorVO> getListByMedicineId(String medicineId) {
        LambdaQueryWrapper<MedicineAuthorEntity> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(MedicineAuthorEntity::getMedicineId, medicineId);
        queryWrapper.orderByAsc(MedicineAuthorEntity::getOrderId);

        List<MedicineAuthorEntity> list= this.list(queryWrapper);
        return list.stream().map(mapping::entity2Vo).collect(Collectors.toList());

    }

    @Override
    public boolean batchRemoveByMedicineIds(List<String> medicineIds) {
        LambdaQueryWrapper<MedicineAuthorEntity> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.in(MedicineAuthorEntity::getMedicineId, medicineIds);
        return this.remove(queryWrapper);
    }
}
